package com.mmall.concurrency.example.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mmall.concurrency.example.atomic.AtomicExample3;

@Slf4j
public class SemaphoreExample2 {
	private static Logger log = LoggerFactory.getLogger(AtomicExample3.class);

    private static int threadCount = 20;

    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();

        final Semaphore semaphore = new Semaphore(3); // 控制同时只能有20个线程访问

        for (int i = 0; i < threadCount; i++) {
            final int threadNumber = i;
            executorService.execute(()->{
                try{
                    semaphore.acquire(3); // 获取多个许可
                    test(threadNumber);
                    semaphore.release(3); // 释放多个许可
                }catch (Exception e){
                    log.error("exception", e);
                }finally {

                }
            });
        }
        log.info("finish");
        executorService.shutdown(); // 如果线程池不再使用，不要忘记关闭
    }

    private static void test(int threadNumber) throws Exception{
        log.info("{}", threadNumber);
        Thread.sleep(100);
    }
}

/*
这时，每次拿三个许可，就是每次输出一个数。 什么意思呢？就是说运行test方法需要三个许可，近似于运行test是单线程执行的
15:29:57.103 [main] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - finish
15:29:57.110 [pool-1-thread-1] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 0
15:29:57.213 [pool-1-thread-2] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 1
15:29:57.313 [pool-1-thread-3] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 2
15:29:57.414 [pool-1-thread-4] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 3
15:29:57.514 [pool-1-thread-5] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 4
15:29:57.615 [pool-1-thread-6] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 5
15:29:57.716 [pool-1-thread-7] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 6
15:29:57.816 [pool-1-thread-8] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 7
15:29:57.917 [pool-1-thread-9] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 8
15:29:58.017 [pool-1-thread-10] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 9
15:29:58.118 [pool-1-thread-11] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 10
15:29:58.219 [pool-1-thread-12] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 11
15:29:58.320 [pool-1-thread-13] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 12
15:29:58.433 [pool-1-thread-14] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 13
15:29:58.551 [pool-1-thread-15] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 14
15:29:58.675 [pool-1-thread-16] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 15
15:29:58.793 [pool-1-thread-17] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 16
15:29:58.895 [pool-1-thread-18] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 17
15:29:59.009 [pool-1-thread-19] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 18
15:29:59.110 [pool-1-thread-20] INFO com.mmall.concurrency.example.aqs.SemaphoreExample2 - 19

Process finished with exit code 0

* */